/// Blinky.NET - a program to reduce eye strain by reminding you to blink
/// Copyright (C) 2007  Forrest Humphrey
///
/// This program is free software; you can redistribute it and/or
/// modify it under the terms of the GNU General Public License
/// as published by the Free Software Foundation; either version 2
/// of the License, or (at your option) any later version.
///
/// This program is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
/// GNU General Public License for more details.
///
/// You should have received a copy of the GNU General Public License
/// along with this program; if not, write to the Free Software
/// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
using System;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;

namespace Blinky {

    /// <summary>
    /// Custom application context responsible for showing the
    /// tray notifier and the BlinkForm.  It also determines when
    /// the application should exit.
    /// </summary>
    sealed class BlinkyApplicationContext : ApplicationContext {

        private IContainer components;
        private NotifyIcon trayIcon;
        private Icon redEyeIcon;
        private Icon greenEyeIcon;
        private OptionsDialog optionsDialog;
        private BlinkForm blinkForm;
        private ContextMenu menu;
        private MenuItem exitMenuItem;
        private MenuItem optionsMenuItem;
        private MenuItem blinkMenuItem;
        private ActivityTracker tracker;

        /// <summary>
        /// Default constructor
        /// 
        /// Initialize the windows forms components, create icons
        /// from the png files in the Project's Resources, and initialize
        /// the OptionsDialog and the ActivityTracker.
        /// </summary>
        /// <returns></returns>
        public BlinkyApplicationContext() {
            InitializeComponent();
            GenerateIcons();

            tracker = new ActivityTracker();
            tracker.BlinkListeners += new TimeToBlinkHandler(OnTimeToBlink);

            InitializeOptions();
        }

        #region Windows forms initialization
        private void InitializeComponent() {
            components = new Container();
            trayIcon = new NotifyIcon(components);
            menu = new ContextMenu();
            exitMenuItem = new MenuItem();
            optionsMenuItem = new MenuItem();
            blinkMenuItem = new MenuItem();

            // blinkMenuItem
            blinkMenuItem.Text = "&Force Blink";
            blinkMenuItem.Click += new EventHandler(blinkMenuItem_Click);

            // exitMenuItem
            exitMenuItem.Text = "E&xit";
            exitMenuItem.Click += new EventHandler(exitMenuItem_Click);

            // optionsMenuItem
            optionsMenuItem.Text = "&Options";
            optionsMenuItem.Click += new EventHandler(optionsMenuItem_Click);

            // trayIcon
            trayIcon.Visible = true;
            trayIcon.ContextMenu = menu;
            trayIcon.DoubleClick += new EventHandler(tray_DoubleClick);

            // menu
            menu.MenuItems.AddRange(new MenuItem[] {
                blinkMenuItem,
                optionsMenuItem,
                exitMenuItem
            });
        }
        #endregion

        private void GenerateIcons() {
            Bitmap tempRedEye = new Bitmap(
                Properties.Resources.red_eye,
                new Size(32, 32));
            Bitmap tempGreenEye = new Bitmap(
                Properties.Resources.green_eye,
                new Size(32, 32));
            redEyeIcon = Icon.FromHandle(tempRedEye.GetHicon());
            greenEyeIcon = Icon.FromHandle(tempGreenEye.GetHicon());

            trayIcon.Icon = greenEyeIcon;
        }

        private void OnTimeToBlink() {
            NotifyBlink();
        }

        void OptionsDialog_FormClosed(object sender, FormClosedEventArgs e) {
            tracker.Reset();
        }

        public void NotifyBlink() {
            blinkForm = new BlinkForm();
            blinkForm.Show();
            blinkForm.Closed += new EventHandler(BlinkForm_Closed);
        }

        private void BlinkForm_Closed(object sender, EventArgs e) {
            blinkForm = null;
        }

        private void InitializeOptions() {
            optionsDialog = new OptionsDialog();
            optionsDialog.FormClosed += new FormClosedEventHandler(OptionsDialog_FormClosed);
        }

        protected override void ExitThreadCore() {
            if (MainForm != null) {
                MainForm.Close();
            }
            base.ExitThreadCore();
        }

        protected override void Dispose(bool disposing) {
            if (disposing) {
                if (components != null) {
                    components.Dispose();
                }
            }
        }

        private void SwitchIcon() {
            if (trayIcon.Icon != null) {
                if (trayIcon.Icon == greenEyeIcon) {
                    trayIcon.Icon = redEyeIcon;
                }
                else {
                    trayIcon.Icon = greenEyeIcon;
                }
            }
        }

        private void PresentOptionsDialog() {
            InitializeOptions();
            optionsDialog.Show();
        }

        #region Event handlers
        private void tray_DoubleClick(object sender, EventArgs e) {
            PresentOptionsDialog();
        }

        private void exitMenuItem_Click(object sender, EventArgs e) {
            ExitThread();
        }

        private void optionsMenuItem_Click(object sender, EventArgs e) {
            PresentOptionsDialog();
        }

        private void blinkMenuItem_Click(object sender, EventArgs e) {
            NotifyBlink();
        }
        #endregion
    }
}
